﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace CSharpShredder
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();           
        }
        public void DoWipe()
        {
            this.WipeButtonEnabled(false);
            if (radio_Wipe_File.Checked)
            {
                this.WipeFile(tbx_File.Text, this.ComboBoxItem);
            }
            else
            {
                if (Directory.Exists(tbx_Folder.Text))
                {
                    this.RecurseDir(new DirectoryInfo(tbx_Folder.Text));
                }
            }
            this.WipeButtonEnabled(true);
        }
        public void RecurseDir(DirectoryInfo dir)
        {
            foreach (DirectoryInfo dInfo in dir.GetDirectories())
            {
                this.RecurseDir(dInfo);
            }
            foreach (FileInfo fInfo in dir.GetFiles())
            {
                this.WipeFile(fInfo.FullName,this.ComboBoxItem);
            }
            try
            {
                dir.Delete();
            }
            catch (IOException ex)
            {
                this.Errors.Add(ex.Message);
            }
            catch (Exception regularex)
            {
                MessageBox.Show(regularex.Message);
            }
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        private void SetStatusBar(string text)
        {
            if (statusStrip1.InvokeRequired)
            {
                SetStatusBarCallback d = new SetStatusBarCallback(SetStatusBar);
                statusStrip1.Invoke(d, new object[] { text });                
            }
            else
            {
                toolStripStatusLabel1.Text = text;
            }
        }
        public System.Threading.Thread workWipe;
        private delegate void SetStatusBarCallback(string text);

        private void button1_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                tbx_Folder.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void btn_Select_File_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                tbx_File.Text = openFileDialog1.FileName;
            }
        }
        private string ChunkData(int SizeOf)
        {
            string OnesorZeroes = "01";
            string OtherVals = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!@#$%^&*()_+[]{};':\",./<>?";
            StringBuilder retval = new StringBuilder();
            Random randGen = new Random(new Random().Next());
            for (int i = 0; i < SizeOf; i++)
            {
                if (radio_1sand0s.Checked)
                    retval.Append(randGen.Next() % 2 == 0 ? OnesorZeroes[0] : OnesorZeroes[1]);
                else
                {
                    retval.Append(OtherVals[(int)(randGen.NextDouble() * OtherVals.Length)]);
                }
            }
            return retval.ToString();
        }
        private void WipeFile(string filename, int count)
        {
            this.SetStatusBar("Wiping file..");            
            if (File.Exists(filename))
            {
                for (int i = 0; i < count; i++)
                {
                    FileStream fStream = File.Open(filename, FileMode.Open);
                    // Get the length of the file.
                    long streamlength = fStream.Length;
                    // Get rid of the stream used to open the file.
                    fStream.Close();
                    fStream.Dispose();
                    // Random generator for fluff data.
                    Random randgen = new Random();
                    // Truncate the file so that our position is 1.
                    fStream = File.Open(filename, FileMode.Open);                    
                    // Set up a writer
                    fStream.Lock(0,streamlength);
                    StreamWriter sWrite = new StreamWriter(fStream);
                    sWrite.AutoFlush = true;
                    sWrite.BaseStream.Position = 0;
                    // Run through the file and chunk out the data.
                    int interval = 1024;
                    while (sWrite.BaseStream.Position < streamlength)
                    {
                        if (interval + sWrite.BaseStream.Position < streamlength)
                            sWrite.Write(ChunkData(interval));
                        else
                        {
                            sWrite.Write(ChunkData(Convert.ToInt32(streamlength - sWrite.BaseStream.Position)));
                        }                        
                    }
                    sWrite.Flush();
                    fStream.Flush();
                    fStream.Unlock(0,streamlength);
                    sWrite.Close();
                    fStream.Close();
                    sWrite.Dispose();
                    fStream.Dispose();
                }
                try
                {                 
                    File.Delete(filename);
                    this.SetStatusBar("Wiped file.");
                }
                catch (Exception ex)
                {
                    Errors.Add(ex.Message);
                }
            }
        }
        private void WipeButtonEnabled(bool enabled)
        {
            if (button3.InvokeRequired)
            {
                EnableButtonCallback d = new EnableButtonCallback(WipeButtonEnabled);
                button3.Invoke(d, new object[] { enabled });
            }
            else
            {
                button3.Enabled = enabled;
            }
        }
        //private void ProgressStep()
        //{
        //    if (toolStripProgressBar1.ProgressBar.InvokeRequired)
        //    {
        //        ProgressCallback d = new ProgressCallback(ProgressStep);
        //        this.toolStripProgressBar1.ProgressBar.Invoke(d);
        //    }
        //    else
        //    {
        //        toolStripProgressBar1.PerformStep();
        //    }
        //}
        //private void ProgressReset()
        //{
        //    if (toolStripProgressBar1.ProgressBar.InvokeRequired)
        //    {
        //        ProgressCallback d = new ProgressCallback(ProgressStep);
        //        this.toolStripProgressBar1.ProgressBar.Invoke(d);
        //    }
        //    else
        //    {
        //        toolStripProgressBar1.Value = 0;
        //    }
        //}
        //private void ProgressMaximum(int maximum)
        //{
        //    if (toolStripProgressBar1.ProgressBar.InvokeRequired)
        //    {
        //        ProgressMaximumCallback d = new ProgressMaximumCallback(ProgressMaximum);
        //        this.toolStripProgressBar1.ProgressBar.Invoke(d, new object[] { maximum });
        //    }
        //    else
        //    {
        //        toolStripProgressBar1.ProgressBar.Maximum = maximum;
        //    }
        //}
        //private void ProgressStepValue(int step)
        //{
        //    if (toolStripProgressBar1.ProgressBar.InvokeRequired)
        //    {
        //        ProgressMaximumCallback d = new ProgressMaximumCallback(ProgressStepValue);
        //        this.toolStripProgressBar1.ProgressBar.Invoke(d, new object[] { step });
        //    }
        //    else
        //    {
        //        toolStripProgressBar1.ProgressBar.Step = step;
        //    }
        //}
        //private void ProgressUpdate()
        //{
        //    if (toolStripProgressBar1.ProgressBar.InvokeRequired)
        //    {
        //        ProgressCallback d = new ProgressCallback(ProgressUpdate);
        //        this.toolStripProgressBar1.ProgressBar.Invoke(d);
        //    }
        //    else
        //    {
        //        toolStripProgressBar1.ProgressBar.Update();
        //    }

        //}
        private delegate void ProgressCallback();
        private delegate void EnableButtonCallback(bool enabled);
        private delegate void ProgressMaximumCallback(int maximum);        
        public List<string> Errors = new List<string>();
        private int ComboBoxItem;
        private void button3_Click(object sender, EventArgs e)
        {            
            if (radio_Wipe_File.Checked && !File.Exists(tbx_File.Text))
                MessageBox.Show("Please select a valid file to wipe.");
            else if (radio_Wipe_Folder.Checked && !Directory.Exists(tbx_Folder.Text))
                MessageBox.Show("Please select a valid folder to wipe clean.");
            else if (comboBox1.SelectedItem == null)
                MessageBox.Show("Please select a number of times to overwrite the file.");
            else
            {
                this.ComboBoxItem = Convert.ToInt32(comboBox1.SelectedItem);
                workWipe = new System.Threading.Thread(new System.Threading.ThreadStart(DoWipe));
                workWipe.Start();
            }
        }
    }
}
